<template>
<div :class="[$style.container]">
  <div :class="[$style.header]">
    <el-button type="primary" size="small" icon="el-icon-plus" @click="onCreate">新建同步</el-button>
    <el-button type="primary" size="small" icon="el-icon-refresh-right" :disabled="selectedRow.status === 'updating'" @click="onStart" v-if="selectedRow">同步</el-button>
    <el-button type="warning" size="small" icon="el-icon-video-pause" :disabled="selectedRow.status !== 'updating'" @click="onStop" v-if="selectedRow">强制停止</el-button>
    <el-button type="danger" size="small" icon="el-icon-delete" @click="onDelete" v-if="selectedRow">删除</el-button>
    <el-button type="primary" size="small" icon="el-icon-setting" @click="onEdit" v-if="selectedRow">设置</el-button>
    <el-button type="info" size="small" icon="el-icon-folder-opened" @click="onOpen" v-if="selectedRow">打开本地目录</el-button>
    <el-button type="info" size="small" icon="el-icon-folder-opened" @click="onForward" v-if="selectedRow">前往云盘位置</el-button>
  </div>
  <div :class="[$style.body]">
    <ul :class="[$style.list]" v-if="renderedRows.length > 0">
      <li :class="[$style.item, selectedCls(row)]" v-for="(row, i) in renderedRows" :key="i" @click="onSelect(row)">
        <div :class="[$style.itemIcon]">
          <svg-icon icon="docs"></svg-icon>
          <div :class="[$style.itemIconStatus]">
            <svg-icon icon="completed" :class="[$style.itemCompletedStatus]" v-if="row.status === 'completed'"></svg-icon>
            <svg-icon icon="updating" :class="[$style.itemUpdatingStatus]" v-if="row.status === 'updating'"></svg-icon>
            <svg-icon icon="pause" :class="[$style.itemPauseStatus]" v-if="row.status === 'pause'"></svg-icon>
            <svg-icon icon="error" :class="[$style.itemErrorStatus]" v-if="row.status === 'error'"></svg-icon>
          </div>
          <div :class="[$style.itemIconType]">
            <svg-icon icon="up" :class="[$style.itemUpType]" v-if="row.type === 'up'"></svg-icon>
            <svg-icon icon="down" :class="[$style.itemDownType]" v-if="row.type === 'down'"></svg-icon>
          </div>
        </div>
        <div :class="[$style.itemText]">
          {{row.name}}
        </div>
        <div :class="[$style.progress]" v-if="row.status === 'updating'">
          <el-progress :percentage="percentage(row)" :show-text="false"></el-progress>
        </div>
      </li>
    </ul>
    <empty-data v-else>
      <template v-slot:icon>
        <svg-icon icon="local-sync"></svg-icon>
      </template>
      <p>本地文件夹与网盘文件夹绑定，实现自动同步、单项上传、单项下载</p>
      <el-button type="primary" size="small" @click="onCreate">创建一个同步盘</el-button>
    </empty-data>
  </div>
  <div :class="[$style.footer]" v-if="selectedRow">
    <span>{{selectedRow.name}}</span>
    <span>类型: {{rowTypeText}}</span>
    <div :class="[$style.footerPath]" v-if="['', 'updating'].includes(selectedRow.status) && selectedRow.updatingInfo">
      <template v-if="selectedRow.updatingInfo.progress !== -1">
        <span v-if="selectedRow.updatingInfo.size !== -1">{{selectedRow.updatingInfo.size | size}}</span>
        <span class="ml-2">{{Math.floor(selectedRow.updatingInfo.progress * 100)}}%</span>
      </template>
      <span v-else> {{selectedRow.updatingInfo.size}}</span>
      <span class="ml-2" :title="selectedRow.updatingInfo.path">{{selectedRow.updatingInfo.path}}</span>
    </div>
    <span v-else>更新时间: {{selectedRow.updateTime | date('datetime')}}</span>
    <span>
      <span class="ft-md">
        <svg-icon icon="completed" class="text-success" v-if="selectedRow.status === 'completed'"></svg-icon>
        <svg-icon icon="updating" class="text-primary" v-if="selectedRow.status === 'updating'"></svg-icon>
        <svg-icon icon="pause" class="text-secondary" v-if="selectedRow.status === 'pause'"></svg-icon>
        <svg-icon icon="error" class="text-error" v-if="selectedRow.status === 'error'"></svg-icon>
      </span>
      <span class="ml-1">{{rowStatusText}}</span>
      <span v-if="selectedRow.status === 'updating'">
        <span v-if="selectedRow.updatingInfo.progress !== -1">({{selectedRow.progress }}/{{selectedRow.total}})</span>
        <span v-else>(计算中...)</span>
      </span>
      <span class="ft-md ml-2" v-if="selectedRow.status === 'error'">
        <el-tooltip :content="selectedRow.message" placement="top">
          <i class="el-icon-info"></i>
        </el-tooltip>
      </span>
    </span>
  </div>
  <create-modal :before-confirm-fn="beforeCreateConfirmFn" ref="createModal"></create-modal>
  <edit-modal ref="editModal"></edit-modal>
</div>
</template>

<script lang="ts">

import { Vue, Component, Provide, Watch, Ref } from 'vue-property-decorator'
import CreateModal from './components/create-modal/index.vue'
import EditModal from './components/edit-modal/index.vue'
import { pull, push } from './sync'
import { store } from './store'
import { remote } from 'electron'
import { AppModule } from '@/store'

const typeMap = {
  duplex: { value: '双向同步' },
  up: { value: '单向上传' },
  down: { value: '单向下载' }
}

const statusMap = {
  completed: { value: '同步完成' },
  updating: { value: '同步中' },
  pasue: { value: '暂停同步' },
  error: { value: '同步失败' }
}

@Component({
  components: { CreateModal, EditModal }
})
export default class Local extends Vue {
  @Ref() createModal!: CreateModal

  @Ref() editModal!: EditModal

  @AppModule.State currentSpace!: any

  selectedRow: any = null

  get rows () {
    return store.drivers
  }

  set rows (value: any[]) {
    store.drivers = value || []
  }

  get renderedRows () {
    return this.rows.filter(v => v?.spaceId === this.currentSpace?.ownId)
  }

  get rowTypeText () {
    return this.selectedRow ? (typeMap as any)[this.selectedRow?.type]?.value : ''
  }

  get rowStatusText () {
    return this.selectedRow ? (statusMap as any)[this.selectedRow?.status]?.value : ''
  }

  beforeCreateConfirmFn (data: any) {
    const has = this.rows.some(v => {
      if (v.docId === data.docId && v.type === data.type) {
        this.$message.warning('所选云端文件夹已绑定，请重新选择')
        return true
      }
      if (v.localPath === data.localPath && v.type === data.type) {
        this.$message.warning('所选本地文件夹文件夹已绑定，请重新选择')
        return true
      }
      return false
    })
    if (!has) {
      this.rows.splice(0, 0, data)
    }
    return has ? Promise.reject(new Error('exists')) : Promise.resolve()
  }

  selectedCls (row: any) {
    return row === this.selectedRow ? this.$style.selected : ''
  }

  percentage (row: any) {
    return Math.min(Math.ceil(100 * (row?.progress || 0) / (row?.total || 1)), 100)
  }

  onSelect (row: any) {
    this.selectedRow = row || null
  }

  onCreate () {
    this.createModal.open().then((data: any) => {
      this.$message.success('已创建')
      if (data.type === 'up') {
        push(data?.id)
      } else if (data.type === 'down') {
        pull(data?.id)
      }
    }).catch(() => {
      // ignore
    })
  }

  onEdit () {
    this.editModal.open(this.selectedRow).then((data: any) => {
      this.$message.success('设置成功')
    }).catch(() => {
      // ignore
    })
  }

  onDelete (row: any) {
    if (!this.selectedRow) return
    this.$confirm('确认删除该网盘, 删除后不可恢复。', '删除网盘', {
      confirmButtonText: '删 除',
      cancelButtonText: '取 消',
      confirmButtonClass: 'el-button--danger',
      type: 'error'
    }).then(() => {
      const rows = this.rows.filter(v => v !== this.selectedRow)
      this.rows = rows
      this.selectedRow = null
      this.$message.success('已删除')
    }).catch(() => {
      // ignore
    })
  }

  onStart () {
    const row = this.selectedRow
    if (row.type === 'up') {
      push(row?.id)
    } else if (row.type === 'down') {
      pull(row?.id, true)
    }
  }

  onStop () {
    if (this.selectedRow) {
      this.selectedRow.status = 'error'
      this.selectedRow.message = '手动终止'
    }
  }

  onOpen () {
    const { shell } = remote
    shell.openPath(this.selectedRow.localPath)
  }

  onForward () {
    const ownId = this.currentSpace?.ownId
    const path = ownId === -1 ? '/docs' : `/ent/${ownId}/docs`
    this.$router.push({ path, query: { id: this.selectedRow?.docId } })
  }

  // created () {
  //   // store.reloadDrivers()
  //   const timer = setInterval(() => {
  //     this.rows.forEach(row => {
  //       if (row.status === 'updating' || row.status === 'error') return
  //       if (!row.updateTime || (Date.now() - row.updateTime > row.period * 1000)) {
  //         push(row.id)
  //       }
  //     })
  //   }, 10 * 1000)
  //   this.$once('hook:beforeDestroy', function () {
  //     if (timer) clearInterval(timer)
  //     store.saveDrivers()
  //   })
  // }

  $style!: any
}
</script>

<style lang="scss" module>
@import "~@/styles/vars.scss";

$header-height: 40px;

.container {
  height: 100%;
  background-color: #fff;
}

.header {
  height: 48px;
  padding: 0 12px;
  border-bottom: 1px solid $border-split-color;
  display: flex;
  align-items: center;
  box-sizing: border-box;
}

.body {
  box-sizing: border-box;
  padding: 12px;
  height: calc(100% - 48px - 40px);
  overflow: auto;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
}

.item {
  padding: 0 10px 8px 12px;
  margin: 0 2px;
  text-align: center;
  border-radius: 2px;
  width: 96px;
  &:hover, &.selected {
    background-color: $color-primary-lighten-5;
    cursor: pointer;
  }
}

.itemIcon {
  color: $color-warning;
  position: relative;
  display: inline-block;
  &>* {
    font-size: 56px;
  }
}

.itemIconStatus {
  position: absolute;
  bottom: 0;
  right: 0;
  font-size: 18px;
  transform: translate(50%, 0);
  width: 18px;
  height: 18px;
}

.progress {
  margin-top: 4px;
  padding: 0 4px;
}

.itemCompletedStatus {
  color: $color-success;
}

.itemUpdatingStatus {
  color: $color-primary;
}

.itemPauseStatus {
  color: $color-info;
}

.itemErrorStatus {
  color: $color-error;
}

.itemIconType {
  position: absolute;
  left: 50%;
  top: 50%;
  font-size: 18px;
  transform: translate(-50%, -50%);
  width: 18px;
  height: 18px;
}

.itemUpType {
  color: #fff;
}

.itemDownType {
  color: #fff;
}

.itemText {
  font-size: 12px;
  word-break: break-all;
}

.footer {
  height: 40px;
  box-sizing: border-box;
  border-top: 1px solid $border-split-color;
  display: flex;
  justify-content: space-between;
  color: $text-secondary-color;
  font-size: 12px;
  align-items: center;
  padding: 0 20px;
}

.footerPath {
  max-width: 480px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
